<script setup lang="ts">
import { Handle, Position, useVueFlow } from '@vue-flow/core'
import { computed, ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
import AddCustomKey from './AddCustomKey.vue';
import StyleSet from './StyleSet.vue';
const props = defineProps<{
  id: string;
  data: {
    name: string;
    custom_keys: Array<CustomKeyHandle>;
    role?: string;
    prompt?: string;
    isSpeak?: boolean;
    isFunctionCall?: boolean;
  };
  toObject?:()=>any
}>()

const { updateNodeData, updateNode, updateNodeInternals } = useVueFlow()

const name = computed({
  get: () => props.data.name,
  set: (name) => updateNodeData(props.id, {...props.data, name: name }),
})

import useConnectionValid from './ts/connectionValid';
import { type CustomKey, type CustomKeyHandle } from './ts/customKey'
const { isValidConnection } = useConnectionValid();


// 定义输入框和复选框的状态
const role = ref(props.data.role);
const prompt = ref(props.data.prompt);
const isSpeak = ref(props.data.isSpeak);
const isFunctionCall = ref(props.data.isFunctionCall);
watch(() => [role.value, prompt.value, isSpeak.value, isFunctionCall.value], () => {
  updateNodeData(props.id, {...props.data, role: role.value, prompt: prompt.value, isSpeak: isSpeak.value, isFunctionCall: isFunctionCall.value })
})

// 定义自定义键的状态
const CustomKeys = ref<Array<CustomKey>>(props.data.custom_keys);
const customKeysHandle = ref<Array<CustomKeyHandle>>(props.data.custom_keys);
watch(() => CustomKeys.value, ()=>{
  customKeysHandle.value = CustomKeys.value.map((key, index) => {
    let value_type = 'msg';
    let class_type = 'AgentMsg';
    switch (key.type) {
      case 'bool':
        value_type = 'bool';
        break;
      case 'int':
        value_type = 'int';
        break;
      default:
        break;
    }
    return {
      type: key.type,
      name: key.name,
      value_type: value_type,
      id: `custom-key-${key.name}-${value_type}`,
      top: index * (30/CustomKeys.value.length) + 65,
      class_type:class_type,
      note:key.note,
      handle_type:key.handle_type||'source',
    };
  });
  
  updateNodeData(props.id, {...props.data, custom_keys: customKeysHandle.value })
  updateNodeInternals(['1'])
},
{ deep: true })


// 监听节点容器大小变化
const AgentContentConainer = ref<HTMLElement | null>(null);
let observer: ResizeObserver;
import { useProjectsStore } from '@/stores/projectsStore';
import type { Styles } from '@vue-flow/core';
let projectStore = useProjectsStore();
onMounted(() => {
  // console.log("props:", props)
    let now_store_node = projectStore.getNode(props.id);
    let STY = <Styles>now_store_node?.style || {};
    if (now_store_node) {
      WW.value = STY?.minWidth ? parseInt(STY.minWidth.toString()) : MaxWW;
      HH.value = STY?.minHeight ? parseInt(STY.minHeight.toString()) : MaxHH;
      Color.value = STY?.backgroundColor || AgentBackground;
    }
    if (!AgentContentConainer.value) return;
    observer = new ResizeObserver(() => {
      if (!AgentContentConainer.value) return;
      updateSize();
      const { width, height } = AgentContentConainer.value!.getBoundingClientRect();
      //console.log('AgentContentConainer:', width, height);
    });
    observer.observe(AgentContentConainer.value);  // 观察元素

});
onUnmounted(()=>{
  if (AgentContentConainer.value) {
    observer.unobserve(AgentContentConainer.value);
  }
})  
defineOptions({
  name: 'AgentNode'
})
import { AgentMinW, AgentMinH, AgentBackground } from './ts/default-node-style';
const MaxWW=AgentMinW;
const MaxHH=AgentMinH;
const WW = ref(MaxWW);
const HH = ref(MaxHH);
const Color= ref('#F5F5F5FF');
const updateColor=(color:string)=>{
  Color.value = color;
  updateSize()
}
const onChangeSize = () => {
  updateSize()
}

const updateSize=()=>{
  WW.value = Math.max(WW.value, MaxWW);
  HH.value = Math.max(HH.value, MaxHH);
  updateNode(props.id, {...props, style:{minWidth: `${WW.value}px`,minHeight: `${HH.value}px`,backgroundColor: Color.value}})
  //console.log('更新样式:',props.toObject?.())
}
</script>

<template>
    <div class="AgentName"> <input :id="`${id}-input`" v-model="name"  class="nodrag"> </div>
    <div class="AgentContent" ref="AgentContentConainer">
      <Handle id="flow-in" type="target" :class="['AgentFlowInputHandle','top-0']" :position="Position.Left" title="FLow In"  :connectable="()=>{return isValidConnection(props.id,'flow-in', 'target')}" ><span class="HandleLeftSpan">Flow In</span></Handle>
      <Handle id="query-msg" type="target" :class="['AgentMsg','top-1']" :position="Position.Left" title="Query"   :connectable="()=>{return isValidConnection(props.id,'query-msg', 'target')}"><span class="HandleLeftSpan" >Query</span></Handle>
      <Handle id="context-msg" type="target" :class="['AgentMsg','top-2']" :position="Position.Left" title="Context"  :connectable="()=>{return isValidConnection(props.id,'context-msg', 'target')}"><span class="HandleLeftSpan" >Context</span></Handle>
      <Handle id="memory-msgs" type="target" :class="['AgentMsgs','top-3']" :position="Position.Left" title="Memory"  :connectable="()=>{return isValidConnection(props.id,'memory-msgs', 'target')}"><span class="HandleLeftSpan" >Memory</span></Handle>
      <Handle id="tools" type="target" :class="['AgentTools','top-4']" :position="Position.Left" title="Tools"  :connectable="()=>{return isValidConnection(props.id,'tools', 'target')}"><span class="HandleLeftSpan" >Tools</span></Handle>
      

      <Handle id="flow-next" type="source" :class="['AgentFlowOutputHandle','top-0']" :position="Position.Right"  :connectable="()=>{return isValidConnection(props.id,'flow-next','source')}" title="FLow Out" ><span class="HandleRightSpan">Flow Out</span></Handle>
      <Handle id="reason-msg" type="source" :class="['AgentMsg','top-1']" :position="Position.Right"  :connectable="()=>{return isValidConnection(props.id,'reason-msg','source')}" title="Reason" ><span class="HandleRightSpan">Reason</span></Handle>
      <Handle id="speak-msg" type="source" :class="['AgentMsg','top-2']" :position="Position.Right"  :connectable="()=>{return isValidConnection(props.id,'speak-msg','source')}" title="Speak" ><span class="HandleRightSpan">Speak</span></Handle>
      <Handle id="function-calls" type="source" :class="['AgentToolCalls','top-3']" :position="Position.Right"  :connectable="()=>{return isValidConnection(props.id,'function-calls','source')}" title="Function Calls" ><span class="HandleRightSpan">Function Calls</span></Handle>

      <div v-for="key in customKeysHandle" :key="key.id" class="custom-key-item">
        <Handle :id="key.id"  :type="key.handle_type||'source'" :class="key.class_type" :position="key.handle_type === 'target'?Position.Left:Position.Right" :connectable="()=>{return isValidConnection(props.id,key.id,key.handle_type||'source')}" :style="{ top: `${key.top}%` }"><span :class="key.handle_type === 'target'?'HandleLeftSpan':'HandleRightSpan'">{{ key.name }}</span></Handle>
      </div>

      <div class="NodeData">
        <div class="input-row">
          <label for="roleInput">Role:</label>
          <input
            id="roleInput"
            type="text"
            v-model="role"
            placeholder="Enter role"
            :class="['text-input','nodrag']"
          />
        </div>

        <div class="input-row">
          <label for="promptInput">Prompt:</label>
          <textarea
            id="promptInput"
            v-model="prompt"
            placeholder="Enter prompt"
            :class="['text-input','nodrag']"
          ></textarea>
        </div>

        <div class="checkbox-row">
          <label for="isSpeak">Is Speak:</label>
          <input
            id="isSpeak"
            type="checkbox"
            v-model="isSpeak"
            :class="['checkbox','nodrag']"
          />
        </div>

        <div class="checkbox-row">
          <label for="isFunctionCall">Is Function Call:</label>
          <input
            id="isFunctionCall"
            type="checkbox"
            v-model="isFunctionCall"
            :class="['checkbox','nodrag']"
          />
        </div>
        <AddCustomKey v-model="CustomKeys" ></AddCustomKey>
      </div>
    </div>
      <div class="setfooter2" style="height:30px;width:200px;">
    W:<span class="input2"> <input :id="`${id}-input1`" v-model="WW" class="nodrag" @change="onChangeSize" min="200" max="1000"> </span>
    H:<span class="input2"> <input :id="`${id}-input2`" v-model="HH" class="nodrag" @change="onChangeSize" min="100" max="500"> </span>
  </div>
  <div class="setfooter" style="height:30px;width:70px;">
    <StyleSet @update_style_color="updateColor"></StyleSet>
  </div>

</template>


<style scoped>
.setfooter{
position: absolute;
right:0;
bottom:3px;
}
.setfooter2{
position: absolute;
left:3px;
bottom:0px;
}
.input2 {
  position: relative;
  display: inline-block;
  font-size: 14px;
  text-align: center;
}
.input2 input {
  max-height: 20px;
  height:30px;
  width: 50px;
  border: none;
  outline: none;
  background: transparent;
  color: #333;
  font-size: 16px;
  padding: 8px 12px;
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
  text-align: center;
  background-color: #00000000;
}
.AgentName {
  position: relative;
  display: inline-block;
  font-size: 14px;
  width: 100%;
  padding-left: 70px;
  padding-right: 70px;
  text-align: center;
}

.AgentName input {
  max-height: 20px;
  height: 100%;
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  color: #333;
  font-size: 16px;
  padding: 8px 12px;
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
  text-align: center;
  background-color: #00000000;
}

/* 输入框聚焦时 */
.AgentName input:focus {
  background-color: #f5f5f5;
  box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.5);
  color: #000;
}

/* 输入框没有内容时（placeholder显示） */
.AgentName input:placeholder-shown {
  color: #ffffff;
}

/* 输入框内容区域边距 */
.AgentName input::placeholder {
  color: #ccc;
  font-style: italic;
}

/* 输入框平滑过渡效果 */
.AgentName input {
  transition: background-color 0.3s, box-shadow 0.3s, color 0.3s;
}
.AgentContent{
  width: 100%;
}
</style>